package linter.linterjava.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import linter.linterjava.POJO.DO.Note;
import linter.linterjava.POJO.DTO.NoteDTO;
import linter.linterjava.POJO.UtilDTO.PageInfoDTO;
import linter.linterjava.POJO.UtilDTO.TypeDTO;
import linter.linterjava.service.NoteService;
import linter.linterjava.mapper.NoteMapper;
import linter.linterjava.utils.UploadFileUtil;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import static linter.linterjava.custom.Constant.*;
import static linter.linterjava.custom.CustomResultType.*;

/**
 * @author 北煜
 */
@Service
public class NoteServiceImpl extends ServiceImpl<NoteMapper, Note> implements NoteService {

    @Resource
    NoteMapper noteMapper;

    @Override
    @CacheEvict(value = "notes", key = "#uuid + ':*'")
    public String creatNote(NoteDTO noteDTO, Long uuid) {
        Note note = new Note();
        Date date = new Date();
        note.setNoteName(noteDTO.getNoteName());
        note.setUserId(uuid);
        note.setCreateTime(date);
        note.setUpdataTime(date);

        MultipartFile file = noteDTO.getFile();
        if (file != null && !file.isEmpty()) {
            String url = UploadFileUtil.uploadImageToQiniu(file, uuid, "Notes");
            if (url == null) {
                return UPLOAD_ERROR;
            }
            note.setNoteCoverImg(url);
        } else {
            System.out.println("没有图片");
            note.setNoteCoverImg(DEFAULT_IMG_URL_NOTE);
        }

        int flag = noteMapper.insert(note);
        return flag != 1 ? CREATION_ERROR : CREATION_SUCCESS;
    }

    @Override
    @CacheEvict(value = "notes", key = "#uuid + ':*'")
    public String updateNoteByNoteId(NoteDTO noteDTO, Long uuid) {
        Note note = new Note();
        Date date = new Date();
        note.setNoteContent(noteDTO.getNoteContent());
        note.setUpdataTime(date);

        if (noteDTO.getNoteName() != null && !"".equals(noteDTO.getNoteName())) {
            note.setNoteName(noteDTO.getNoteName());
        } else {
            note.setNoteName(DEFAULT_USER_NAME);
        }

        MultipartFile file = noteDTO.getFile();
        if (file != null && !file.isEmpty()) {
            String url = UploadFileUtil.uploadImageToQiniu(file, uuid, "Notes");
            if (url == null) { return UPLOAD_ERROR; }
            note.setNoteCoverImg(url);
        } else {
            String oUrl = noteMapper.selectOne(new QueryWrapper<Note>()
                            .eq("id", noteDTO.getId())
                            .eq("user_id", uuid)
                            .eq("is_delete", 0))
                    .getNoteCoverImg();
            note.setNoteCoverImg(oUrl);
        }

        note.setViewTime(date);
        int flag = noteMapper.update(note, new QueryWrapper<Note>()
                .eq("user_id", uuid).eq("id", noteDTO.getId()).eq("is_delete", 0));
        return flag != 1 ? UPDATE_ERROR : UPDATE_SUCCESS;
    }

    @Override
    @CacheEvict(value = "notes", key = "#uuid + ':*'")
    public String deleteNoteByNoteId(Long noteId, Long uuid) {
        QueryWrapper<Note> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", noteId).eq("user_id", uuid).eq("is_delete", 0);
        Note note = noteMapper.selectOne(queryWrapper);
        if (note == null) {
            return DELETE_ERROR;
        }
        note.setIsDelete(1);
        int flag = noteMapper.update(note, queryWrapper);
        return flag != 1 ? DELETE_ERROR : DELETE_SUCCESS;
    }

    @Override
    @Cacheable(value = "notes", key = "#uuid + ':queryNote:' + #pageInfoDTO.pageNum + ':' + #pageInfoDTO.pageSize")
    public PageInfo<Note> queryNote(PageInfoDTO pageInfoDTO, Long uuid) {
        int pageSize = Optional.ofNullable(pageInfoDTO.getPageSize()).orElse(10);
        int pageNum = Optional.ofNullable(pageInfoDTO.getPageNum()).orElse(1);
        PageHelper.startPage(pageNum, pageSize);
        QueryWrapper<Note> queryWrapper = new QueryWrapper<>();
        List<Note> list = noteMapper.selectList(queryWrapper
                .eq("user_id", uuid).eq("is_delete", 0).eq("note_knowledgeBase_id", 0));
        return new PageInfo<>(list);
    }


    @Override
    @Cacheable(value = "notes", key = "#uuid + ':' + #pageInfoDTO.pageNum + ':' + #pageInfoDTO.pageSize")
    public PageInfo<Note> queryAllNote(Long uuid, PageInfoDTO pageInfoDTO) {
        int pageSize = Optional.ofNullable(pageInfoDTO.getPageSize()).orElse(10);
        int pageNum = Optional.ofNullable(pageInfoDTO.getPageNum()).orElse(1);
        PageHelper.startPage(pageNum, pageSize);
        QueryWrapper<Note> queryWrapper = new QueryWrapper<>();
        List<Note> list = noteMapper.selectList(queryWrapper.eq("user_id", uuid).eq("is_delete", 0));
        return new PageInfo<>(list);
    }

    @Override
    @Cacheable(value = "notes", key = "#uuid + ':' + #typeDTO.getType() + ':' + #typeDTO.getTypeTime() + ':' + #typeDTO.getData()")
    public Object queryNoteByNoteAbout(TypeDTO<?> typeDTO, Long uuid) {
        QueryWrapper<Note> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", uuid).eq("is_delete", 0);

        Object result = null;

        if (typeDTO.getData() != null) {
            queryWrapper.like("id", "%" + typeDTO.getData().toString() + "%")
                    .or().like("note_name", "%" + typeDTO.getData().toString() + "%")
                    .or().like("note_content", "%" + typeDTO.getData().toString() + "%");
            result = noteMapper.selectList(queryWrapper);
        } else if (typeDTO.getTypeTime() != null) {
            switch (typeDTO.getTypeTime()) {
                case 1:
                    queryWrapper.orderByDesc("create_time");
                    break;
                case 2:
                    queryWrapper.orderByAsc("create_time");
                    break;
                case 3:
                    queryWrapper.orderByDesc("updata_time");
                    break;
                default:
                    result = Collections.emptyList();
            }
            if (result == null) {
                result = noteMapper.selectList(queryWrapper);
            }
        } else if (typeDTO.getType() != null) {
            switch (typeDTO.getType()) {
                case "view":
                    queryWrapper.orderByDesc("view_time");
                    break;
                case "update":
                    queryWrapper.orderByDesc("updata_time");
                    break;
                default:
                    result = Collections.emptyList();
            }
            if (result == null) {
                result = noteMapper.selectList(queryWrapper);
            }
        } else {
            result = Collections.emptyList();
        }
        return result;
    }

    @Override
    public String viewNote(Long noteId, Long uuid) {
        Note note = new Note();
        Date date = new Date();
        note.setViewTime(date);
        QueryWrapper<Note> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", noteId).eq("user_id", uuid);
        int flag = noteMapper.update(note, queryWrapper);
        return flag > 0 ? VIEWS_SUCCESS : VIEWS_ERROR;
    }
}
